<template>
  <div class="monaco-editor-container">
    <div 
      ref="editorContainer" 
      class="editor-wrapper"
      :style="{ height: height, width: width }"
    ></div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue'
import * as monaco from 'monaco-editor'
import loader from '@monaco-editor/loader'

interface Props {
  modelValue?: string
  language?: string
  theme?: string
  height?: string
  width?: string
  options?: monaco.editor.IStandaloneEditorConstructionOptions
  readonly?: boolean
}

interface Emits {
  (e: 'update:modelValue', value: string): void
  (e: 'change', value: string): void
  (e: 'focus'): void
  (e: 'blur'): void
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: '',
  language: 'javascript',
  theme: 'vs-dark',
  height: '400px',
  width: '100%',
  readonly: false,
  options: () => ({})
})

const emit = defineEmits<Emits>()

const editorContainer = ref<HTMLElement>()
let editor: monaco.editor.IStandaloneCodeEditor | null = null
let isEditorReady = false

// 默认编辑器选项
const defaultOptions: monaco.editor.IStandaloneEditorConstructionOptions = {
  automaticLayout: true,
  fontSize: 14,
  lineNumbers: 'on',
  roundedSelection: false,
  scrollBeyondLastLine: false,
  readOnly: props.readonly,
  minimap: {
    enabled: false
  },
  wordWrap: 'on',
  folding: true,
  lineDecorationsWidth: 20,
  lineNumbersMinChars: 3,
  glyphMargin: false,
  contextmenu: true,
  mouseWheelZoom: true,
  smoothScrolling: true,
  cursorBlinking: 'blink',
  cursorSmoothCaretAnimation: 'on',
  renderWhitespace: 'selection',
  renderControlCharacters: false,
  fontLigatures: true,
  fixedOverflowWidgets: true
}

// 初始化Monaco编辑器
const initEditor = async () => {
  if (!editorContainer.value) return

  try {
    // 配置Monaco CDN
    loader.config({
      paths: {
        vs: 'https://cdn.jsdelivr.net/npm/monaco-editor@0.44.0/min/vs'
      }
    })

    const monacoInstance = await loader.init()
    
    // 合并选项
    const editorOptions = {
      ...defaultOptions,
      ...props.options,
      value: props.modelValue,
      language: props.language,
      theme: props.theme,
      readOnly: props.readonly
    }

    // 创建编辑器实例
    editor = monacoInstance.editor.create(editorContainer.value, editorOptions)
    isEditorReady = true

    // 监听内容变化
    editor.onDidChangeModelContent(() => {
      if (!editor) return
      const value = editor.getValue()
      emit('update:modelValue', value)
      emit('change', value)
    })

    // 监听焦点事件
    editor.onDidFocusEditorText(() => {
      emit('focus')
    })

    editor.onDidBlurEditorText(() => {
      emit('blur')
    })

    // 设置编辑器主题
    monacoInstance.editor.setTheme(props.theme)

    // 注册常用的代码片段
    registerCodeSnippets(monacoInstance)

  } catch (error) {
    console.error('Failed to initialize Monaco Editor:', error)
  }
}

// 注册代码片段
const registerCodeSnippets = (monacoInstance: typeof monaco) => {
  // JavaScript/TypeScript 代码片段
  monacoInstance.languages.registerCompletionItemProvider('javascript', {
    provideCompletionItems: (model, position) => {
      const word = model.getWordUntilPosition(position);
      const range = {
        startLineNumber: position.lineNumber,
        endLineNumber: position.lineNumber,
        startColumn: word.startColumn,
        endColumn: word.endColumn
      };
      return {
        suggestions: [
          {
            label: 'console.log',
            kind: monacoInstance.languages.CompletionItemKind.Snippet,
            insertText: 'console.log(${1:message});',
            insertTextRules: monacoInstance.languages.CompletionItemInsertTextRule.InsertAsSnippet,
            documentation: 'Log output to console',
            range: range
          },
          {
            label: 'function',
            kind: monacoInstance.languages.CompletionItemKind.Snippet,
            insertText: 'function ${1:name}(${2:params}) {\n\t${3:// code}\n}',
            insertTextRules: monacoInstance.languages.CompletionItemInsertTextRule.InsertAsSnippet,
            documentation: 'Create a function',
            range: range
          },
          {
            label: 'for',
            kind: monacoInstance.languages.CompletionItemKind.Snippet,
            insertText: 'for (let ${1:i} = 0; ${1:i} < ${2:array}.length; ${1:i}++) {\n\t${3:// code}\n}',
            insertTextRules: monacoInstance.languages.CompletionItemInsertTextRule.InsertAsSnippet,
            documentation: 'For loop',
            range: range
          }
        ]
      }
    }
  })
}

// 更新编辑器值
const updateEditorValue = (newValue: string) => {
  if (!editor || !isEditorReady) return
  
  const currentValue = editor.getValue()
  if (currentValue !== newValue) {
    editor.setValue(newValue)
  }
}

// 更新编辑器语言
const updateEditorLanguage = (newLanguage: string) => {
  if (!editor || !isEditorReady) return
  
  const model = editor.getModel()
  if (model) {
    monaco.editor.setModelLanguage(model, newLanguage)
  }
}

// 更新编辑器主题
const updateEditorTheme = (newTheme: string) => {
  if (!editor || !isEditorReady) return
  
  monaco.editor.setTheme(newTheme)
}

// 更新编辑器选项
const updateEditorOptions = (newOptions: monaco.editor.IStandaloneEditorConstructionOptions) => {
  if (!editor || !isEditorReady) return
  
  editor.updateOptions(newOptions)
}

// 获取编辑器实例
const getEditor = () => editor

// 格式化代码
const formatCode = async () => {
  if (!editor || !isEditorReady) return
  
  await editor.getAction('editor.action.formatDocument')?.run()
}

// 监听props变化
watch(() => props.modelValue, updateEditorValue)
watch(() => props.language, updateEditorLanguage)
watch(() => props.theme, updateEditorTheme)
watch(() => props.options, updateEditorOptions, { deep: true })
watch(() => props.readonly, (newReadonly) => {
  updateEditorOptions({ readOnly: newReadonly })
})

// 组件挂载时初始化编辑器
onMounted(async () => {
  await nextTick()
  await initEditor()
})

// 组件卸载时销毁编辑器
onUnmounted(() => {
  if (editor) {
    editor.dispose()
    editor = null
    isEditorReady = false
  }
})

// 暴露方法给父组件
defineExpose({
  getEditor,
  formatCode,
  updateValue: updateEditorValue,
  updateLanguage: updateEditorLanguage,
  updateTheme: updateEditorTheme,
  updateOptions: updateEditorOptions
})
</script>

<style scoped>
.monaco-editor-container {
  border: 1px solid #d9d9d9;
  border-radius: 6px;
  overflow: hidden;
  background: #1e1e1e;
}

.editor-wrapper {
  position: relative;
}

/* 深色主题样式 */
:deep(.monaco-editor) {
  font-family: 'Fira Code', 'Consolas', 'Monaco', 'Courier New', monospace;
}

:deep(.monaco-editor .margin) {
  background-color: #1e1e1e;
}

:deep(.monaco-editor .monaco-editor-background) {
  background-color: #1e1e1e;
}

/* 浅色主题样式 */
:deep(.monaco-editor.vs) {
  border-color: #e8e8e8;
}

:deep(.monaco-editor.vs .margin) {
  background-color: #f8f8f8;
}

:deep(.monaco-editor.vs .monaco-editor-background) {
  background-color: #ffffff;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .monaco-editor-container {
    border-radius: 4px;
  }
  
  :deep(.monaco-editor) {
    font-size: 12px;
  }
}
</style>